<?php
/**
 * Created by Creatint.
 * Date: 2016/7/19
 * PHP version: +7.0
 * Remark: 若PHP版本低于7.0，请修改以下几个方法：http.
 */

namespace Admin\Tool;

use Admin\Controller\WechatController;
use Admin\Tool\WechatException;

class Wechat{
    /**
     * @var 数据
     */
    private $_receive;      //接受到的xml转换为数组
    private $_funcflag;     //是否标星
    private $_msg;           //回复消息的数组


    /**
     * 消息类型 常量
     */
    const MSG_TYPE_TEXT         =   'text';
    const MSG_TYPE_IMAGE        =   'image';
    const MSG_TYPE_VIDEO        =   'video';
    const MSG_TYPE_VOICE        =   'voice';
    const MSG_TYPE_LOCATION     =   'location';
    const MSG_TYPE_EVENT        =   'event';
    const MSG_TYPE_NEWS         =   'news';
    const MSG_TYPE_LINK         =   'link';
    const MSG_TYPE_MUSIC        =   'music';


    /**
     * @var array 工具类配置数组
     */
    private $_CONFIG = array(
        'MONITOR_SIGNAGURE'   =>   ture,
    );


    /**
     * Wechat constructor.
     * 初始化微信工具类，传入令牌密钥等
     * @param array $officialAccount
     */
    public function __construct(array $officialAccount){
        file_put_contents('/var/www/wechat/flag.log',date("Y-m-d H:i:s")."： \n ".__LINE__."\n ".__FILE__." \n\n",FILE_APPEND);
        //echo 'wechat';
        //echo $officialAccount['token'];
        $this->_CONFIG['appid']              =       $officialAccount['appid'];
        $this->_CONFIG['appsecret']         =        $officialAccount['appsecret'];
        $this->_CONFIG['token']              =       $officialAccount['token'];
        $this->_CONFIG['encodingaeskey']    =       $officialAccount['encodingaeskey'];
        file_put_contents('/var/www/wechat/flag.log',date("Y-m-d H:i:s")."： \n ".__LINE__."\n ".__FILE__." \n\n",FILE_APPEND);

    }

// +----------------------------------------------------------------------
// | 工具方法
// +----------------------------------------------------------------------

    /**
     * 获取微信的xml数据，转化为对象
     * @return $this
     * @throws \Admin\Tool\WechatException
     */
    public function getWechatMessage(){
        file_put_contents('/var/www/wechat/flag.log',date("Y-m-d H:i:s")."： \n ".__LINE__."\n ".__FILE__." \n\n",FILE_APPEND);
        if(empty($tmpStr = file_get_contents("php://input"))){ //获取微信服务器信息
            throw new WechatException('微信消息为空', 500005);
        }
        file_put_contents('/var/www/wechat/receive_xml.log',date("Y-m-d H:i:s")."： \n {$tmpStr}\n\n",FILE_APPEND);
        /* 解析xml数据*/
        libxml_disable_entity_loader(true);
        if(empty($this->_receive = (array)simplexml_load_string($tmpStr, 'SimpleXMLElement', LIBXML_NOCDATA))){
            throw new WechatException('xml字符串转对象出错', 500006);
        }else{
            return $this;
        }

    }



    /**
     * HTTP请求 POST & GET
     * @param  string   $url      请求url
     * @param  array    $param    请求参数
     * @param  string   $method   请求方法 get、post
     * @return string             返回数据
     */
    public function http(string $url = '', array $param = array(), string $method = '', array $header = array()){
        $Curl = curl_init();
        $opt = array();
        $opt[CURLOPT_SSL_VERIFYPEER]    =   false;
        $opt[CURLOPT_SSL_VERIFYHOST]    =   false;
        $opt[CURLOPT_RETURNTRANSFER]    =   1;
        $opt[CURLOPT_TIMEOUT]            =   30;
        $opt[CURLOPT_HEADER]             =   $header;

        if(false === stripos($url, 'http://') && false === stripos($url, 'https://')){
            throw new WechatException('http方法url参数不正确', 500002);
        }
        if('GET' === strtoupper($method)){
            $opt[CURLOPT_URL]   =   $url.'?'.http_build_query($param);
        }elseif('POST' === strtoupper($method)){
            $opt[CURLOPT_URL]   =   $url;
            $opt[CURLOPT_POST]  =   1;
            $opt[CURLOPT_POSTFIELDS]    =   $param;
        }else{
            throw new WechatException('http方法method异常', 500003);
        }
        curl_setopt_array($Curl, $opt);
        $return =   curl_exec($Curl);
        $error  =   curl_error($Curl);
        curl_close($Curl);
        if($error) new WechatException('http方法请求异常 '.$error, 500004);


        return $return;
    }


    /**
     * 检验signature
     * @return bool
     */
    public function checkSignagure(){
        $signature  =   I("get.signature", '');
        $timestamp  =   I("get.timestamp", '');
        $nonce      =   I("get.nonce", '');
        $token      =   $this->_CONFIG['token'];
        $tmpArr     =   array( $timestamp, $nonce, $token);
        sort($tmpArr, SORT_STRING);
        $tmpStr     =   implode($tmpArr);
        //echo $tmpStr;
        if($this->_CONFIG['MONITOR_SIGNAGURE']) file_put_contents('/var/www/wechat/montor.log',__LINE__." {$tmpStr}\n",FILE_APPEND);
        $tmpStr     =   sha1($tmpStr);
        //echo $tmpStr;
        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }


    public function CreatMessage(){

    }

    public function reply($msg = array(), $return = false){
        $xml = $this->xml_encode($msg);
        file_put_contents('/var/www/wechat/send_xml.log',date("Y-m-d H:i:s")."： \n {$xml}\n\n",FILE_APPEND);

        return $xml;
    }

// +----------------------------------------------------------------------
// | 构建回复消息数组的方法
// +----------------------------------------------------------------------


    /**
     * 构造文本消息回复数组
     * @param string $text
     * @return $this
     * @throws \Admin\Tool\WechatException
     */
    public function text($text = ''){
        $msg = array(
            'ToUserName'=>$this->MsgFrom(),
            'FromUserName'=>$this->MsgTo(),
            'MsgType'=>self::MSG_TYPE_TEXT,
            'Content'=>$this->text_filter($text?$text:(!empty($this->MsgContent())?:'默认回复消息')),
            'CreateTime'=>time(),
            'FuncFlag'=>$this->_funcflag?1:0,
        );
        //$this->CreatMessage($msg);
        $this->_msg = $msg;
        return $this;
    }



// +----------------------------------------------------------------------
// | 返回微信消息属性
// +----------------------------------------------------------------------


    /**
     * 返回消息类型 小写
     * @return mixed
     * @throws \Admin\Tool\WechatException
     */
    public function MsgType(){
        if(preg_match('/^[a-zA-Z]{4,10}$/', $this->_receive['MsgType'])){
            return strtolower($this->_receive['MsgType']);
        }else{
            throw new WechatException('消息类型非法', 500007);
            return false;
        }
    }

    public function MsgID(){
        if(preg_match('/^[a-z]{4,10}$/', $this->_receive['MsgID'])){
            return $this->_receive['MsgID'];
        }else{
            throw new WechatException('消息ID非法', 500008);
            return false;
        }
    }


    /**
     * 获取消息发送者
     * @return mixed
     * @throws \Admin\Tool\WechatException
     */
    public function MsgFrom(){
        if(!empty($this->_receive['FromUserName'])){
            return $this->_receive['FromUserName'];
        }else{
            throw new WechatException('消息发送者信息非法', 500009);
            return false;
        }
    }


    /**
     * 获取消息接受者
     * @return mixed
     * @throws \Admin\Tool\WechatException
     */
    public function MsgTo(){
        if(!empty($this->_receive['ToUserName'])){
            return $this->_receive['ToUserName'];
        }else{
            throw new WechatException('消息接受者信息非法', 500010);
            return false;
        }
    }

    /**
     * 获取消息创建时间
     * @return mixed
     * @throws \Admin\Tool\WechatException
     */
    public function MsgTime(){
        if(!empty($this->_receive['CreateTime'])){
            return $this->_receive['CreateTime'];
        }else{
            throw new WechatException('消息创建时间非法', 500011);
            return false;
        }
    }

    /**
     * 获取文本或语音翻译文本
     * @return mixed
     * @throws \Admin\Tool\WechatException
     */
    public function MsgContent(){
        if (!empty($this->_receive['Content'])){
            return $this->_receive['Content'];
        }elseif (!empty($this->_receive['Recongnition'])){
            return $this->_receive['Recongnition'];
        }else{
            throw new WechatException('文本信息或语音文本信息非法', 500012);
            return false;
        }
    }



}